unit smClassGUI;

interface

uses
  SysUtils, Lua, Gen2;

const
  luaCLASS_GUI: AnsiString = 'GUI';
  luaCLASS_PANEL: AnsiString = 'GUIPanel';

  procedure OpenClass(const Lua: lua_State);

implementation

uses
  smLuaUtils, smGUI, smGUIPanel, smExceptions;

function _GUIGetPanel(L: lua_State): Integer; cdecl; forward;
function _GUIUnmodal(L: lua_State): Integer; cdecl; forward;
function _GUIPanelName(L: lua_State): Integer; cdecl; forward;
function _GUIPanelVisible(L: lua_State): Integer; cdecl; forward;
function _GUIPanelToggleVisible(L: lua_State): Integer; cdecl; forward;
function _GUIPanelEnabled(L: lua_State): Integer; cdecl; forward;
function _GUIPanelToggleEnabled(L: lua_State): Integer; cdecl; forward;
function _GUIPanelBringToFront(L: lua_State): Integer; cdecl; forward;
function _GUIPanelShowModal(L: lua_State): Integer; cdecl; forward;

const
  GUI_FUNCS: array [0..10] of luaL_reg = (
    (name: 'Panel'; func: _GUIGetPanel),
    (name: 'Unmodal'; func: _GUIUnmodal),
    (name: nil; func: nil),
    (name: 'Name'; func: _GUIPanelName),
    (name: 'Visible'; func: _GUIPanelVisible),
    (name: 'ToggleVisible'; func: _GUIPanelToggleVisible),
    (name: 'Enabled'; func: _GUIPanelEnabled),
    (name: 'ToggleEnabled'; func: _GUIPanelToggleEnabled),
    (name: 'BringToFront'; func: _GUIPanelBringToFront),
    (name: 'ShowModal'; func: _GUIPanelShowModal),
    (name: nil; func: nil)
  );

function MacroGetPanel(const L: lua_State): TGUIPanel;
begin
  if lua_isuserdata(L, 1) then
  begin
    Result := Pointer(PCardinal(lua_touserdata(L, 1))^);
    if not Assigned(Result) then
      raise ELuaException.Create(L, 'bad panel pointer');
  end
  else
    raise ELuaArgumentCheck.Create(L, 'panel is not specified');
end;

function _GUIGetPanel;
var
  Temp: TGUIElement;
begin
  try
    if lua_isstring(L, 1) then
    begin
      Temp := GUIManager.Panels[lua_tostring(L, 1)];
      if Assigned(Temp) then
      begin
        SetObject(Temp, luaCLASS_PANEL);
        Result := 1;
      end
      else
        raise ELuaArgumentCheck.CreateFmt(
          L, 'panel "%s" not found', [lua_tostring(L, 1)]
        );
    end
    else
      raise ELuaArgumentCheck.Create(L, 'not a valid panel name');

  except
    Result := 0;
  end;
end;

function _GUIUnmodal;
begin
  Result := 0;

  try
    if lua_isnumber(L, 1) then
    begin
      GUIManager.ReleaseModal(lua_tointeger(L, 1));
      SetFieldInt(luaCLASS_GUI, 'ModalResult', GUIManager.ModalResult);
    end
    else
      raise ELuaArgumentCheck.Create(L, 'not a valid modal result');

  except
    // do nothing...
  end;
end;

function _GUIPanelName;
begin
  try
    with MacroGetPanel(L) do
      lua_pushstring(L, PAnsiChar(Name));

    Result := 1;
  except
    Result := 0;
  end;
end;

function _GUIPanelVisible;
begin
  try
    with MacroGetPanel(L) do
    begin
      if lua_gettop(L) > 1 then
        if lua_isboolean(L, 2) then
          Visible := lua_toboolean(L, 2)
        else
          raise ELuaArgumentCheck.Create(L, 'parameter must be boolean');

      lua_pushboolean(L, Visible);
    end;

    Result := 1;
  except
    Result := 0;
  end;
end;

function _GUIPanelToggleVisible;
begin
  try
    with MacroGetPanel(L) do
    begin
      Visible := not Visible;
      lua_pushboolean(L, Visible);
    end;

    Result := 1;
  except
    Result := 0;
  end;
end;

function _GUIPanelEnabled;
begin
  try
    with MacroGetPanel(L) do
    begin
      if lua_gettop(L) > 1 then
        if lua_isboolean(L, 2) then
          Enabled := lua_toboolean(L, 2)
        else
          raise ELuaArgumentCheck.Create(L, 'parameter must be boolean');

      lua_pushboolean(L, Enabled);
    end;

    Result := 1;
  except
    Result := 0;
  end;
end;

function _GUIPanelToggleEnabled;
begin
  try
    with MacroGetPanel(L) do
    begin
      Enabled := not Enabled;
      lua_pushboolean(L, Enabled);
    end;

    Result := 1;
  except
    Result := 0;
  end;
end;

function _GUIPanelBringToFront;
var
  Temp: TGUIPanel;
begin
  Result := 0;

  try
    Temp := MacroGetPanel(L);
    Temp.Owner.PanelList.Pop(Temp);
  except
    // do nothing...
  end;
end;

function _GUIPanelShowModal;
begin
  Result := 0;

  try
    GUIManager.ShowModal(MacroGetPanel(L));
  except
    // do nothing...
  end;
end;

procedure OpenClass;
begin
  // Register class "GUI" and corresponding functions
  SetClass(luaCLASS_GUI, @GUI_FUNCS[0]);
  SetInterface(luaCLASS_PANEL, @GUI_FUNCS[3]);

  // Register read-only fields
  SetFieldInt(luaCLASS_GUI, 'ModalResult', 0);
end;

end.
